#include "CombatSystem.h"
#include "DirectionalAbility.h"
#include "TargettedAbility.h"
#include "NonTargettedAbility.h"

namespace Combat
{
	
	static inline float getTargetDistance( Combatant* me, Combatant* target )
	{
		Maths::Vector3D position, targetPosition;
		position = me->Position();
		targetPosition = target->Position();

		return targetPosition.Distance(position);
	}
	void System::SubmitRequest( Pointer<Request> request )
	{
		m_requests.push_back(request);
	}
	void System::EvaluateRequests( )
	{
		for (Request::List_t::iterator it = m_requests.begin(); it != m_requests.end(); ++it)
		{
			Evaluate(*it);
		}
		m_requests.clear();
	}
	void System::Evaluate( Request* request )
	{
		Combatant* requester = request->requester;
		IAbility* ability = requester->Abilities()[request->ability];

		if (request->Type() == TargettedRequest::type)
		{
			Response response;

			TargettedRequest* targettedRequest = (TargettedRequest*)(request);
			TargettedAbility* targettedAbility = (TargettedAbility*)(ability);

			if (ability->isOffCooldown() && targettedAbility->Range() >= getTargetDistance(requester, targettedRequest->target))
			{
				ability->setCooldownTime();
				requester->ActivatePreAttackEffects( response );

				targettedAbility->Activate(targettedRequest->target, response);
			
				targettedRequest->target->ActivatePreDefenseEffects(response);

				targettedRequest->target->HandleResponse(response);

				targettedRequest->target->ActivatePostDefenseEffects(response);
				requester->ActivatePostAttackEffects(response);
			}

		} else if (request->Type() == DirectionalRequest::type)
		{
			DirectionalRequest* directionalRequest = (DirectionalRequest*)(request);
			DirectionalAbility* directionalAbility = (DirectionalAbility*)(ability);

			directionalAbility->Activate(directionalRequest->direction);
		} else
		{
			NonTargettedAbility* nonTargettedAbility = (NonTargettedAbility*)(ability);

			nonTargettedAbility->Activate();
		}
	}
};